package com.xtaller.sdboot.controller;

import com.xtaller.sdboot.entity.IamModule;
import com.xtaller.sdboot.entity.IamPermission;
import com.xtaller.sdboot.service.IamModuleService;
import com.xtaller.sdboot.service.IamPermissionService;
import com.xtaller.sdboot.core.R;
import com.xtaller.sdboot.core.base.BaseController;
import com.xtaller.sdboot.core.base.BaseEntity;
import com.xtaller.sdboot.utils.annotation.Permission;
import com.xtaller.sdboot.utils.helper.JsonHelper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.Serializable;
import java.util.Collections;
import java.util.Comparator;

/** 
* 代码生成 
* @author: Taller  
* @date: 2020-02-07 15:56:33
* @Description: 权限控制器 
*/ 
@RestController 
@RequestMapping("/v1/iam/permission") 
public class IamPermissionController extends BaseController<IamPermission> {
    @Autowired private IamModuleService moduleService;
    @Autowired private IamPermissionService permissionService;

    @Permission(authorities = "iam:permission:data:list")
    @GetMapping("/get/all")
    public Object getAllByModule(){
        var moduleQw = new QueryWrapper<IamModule>();
        moduleQw.lambda().select(BaseEntity::getId, IamModule::getName, IamModule::getCode, IamModule::getSortId)
                .eq(IamModule::getState, 1)
                .orderByDesc(IamModule::getSortId);
        var modules = moduleService.getList(moduleQw);
        var data = JsonHelper.list();
        if(modules.size() > 0){
            modules.stream().forEach(x -> {
                var module = JsonHelper.create("id", x.getId())
                        .put("pid", "0")
                        .put("mid", x.getId())
                        .put("uri", "")
                        .put("icon", "")
                        .put("flag", "")
                        .put("event", "")
                        .put("sortId", x.getSortId())
                        .put("name", x.getName())
                        .put("state", x.getState())
                        .put("position", "0")
                        .put("title", x.getName());
                data.add(module);
            });
        }
        // 读取所有的权限
        var permissionQw = new QueryWrapper<IamPermission>();
        permissionQw.lambda()
                .orderByDesc(IamPermission::getModuleId)
                .orderByDesc(IamPermission::getSortId)
                .orderByDesc(IamPermission::getParentId)
                .orderByDesc(IamPermission::getState)
                .orderByDesc(IamPermission::getGroups)
                .orderByDesc(IamPermission::getPosition);
        var permissions = permissionService.getList(permissionQw);
        if(permissions.size() > 0){
            Collections.sort(permissions, new IamPermissionPositionComparetor());
            permissions.stream().forEach(x -> {
                var permission = JsonHelper.create("id", x.getId())
                        .put("pid", x.getParentId())
                        .put("mid", x.getModuleId())
                        .put("uri", x.getUri())
                        .put("icon", x.getIcon())
                        .put("flag", x.getFlag())
                        .put("event", x.getEvent())
                        .put("state", x.getState())
                        .put("groups", x.getGroups())
                        .put("remark", x.getRemark())
                        .put("sortId", x.getSortId())
                        .put("name", x.getName())
                        .put("position", x.getPosition())
                        .put("title", x.getName());
                data.add(permission);
            });
        }
        return R.ok(data);
    }

    /**
     * 给权限排序
     * */
    public class IamPermissionPositionComparetor implements Comparator<IamPermission> {
        @Override
        public int compare(IamPermission h1, IamPermission h2) {
            if (h1.getPosition() < h2.getPosition()) {
                return 1;
            } else if (h1.getPosition().equals(h2.getPosition())) {
                return 0;
            } else {
                return -1;
            }
        }
    }

    @Override
    protected String beforeDelete(BaseEntity entity) throws Exception {
        var qw = new QueryWrapper<IamPermission>();
        qw.lambda().eq(IamPermission::getParentId, entity.getId());
        if(permissionService.getList(qw).size() > 0){
            return "不能直接删除有子集的数据";
        }
        return super.beforeDelete(entity);
    }

    @Permission(authorities = "iam:permission:opt:create")
    @Override
    public Object createEntity(@Valid @RequestBody IamPermission entity, HttpServletRequest request) throws Exception {
        return super.createEntity(entity, request);
    }

    @Permission(authorities = "iam:permission:opt:update")
    @Override
    public Object updateEntity(@PathVariable("id") Serializable id, @Valid @RequestBody IamPermission entity, HttpServletRequest request) throws Exception {
        return super.updateEntity(id, entity, request);
    }

    @Permission(authorities = "iam:permission:opt:delete")
    @Override
    public Object deleteEntity(@PathVariable("id") Serializable id, HttpServletRequest request) throws Exception {
        return super.deleteEntity(id, request);
    }

    @Override
    protected String beforeCreate(BaseEntity entity) throws Exception {
        var permission = (IamPermission)entity;
        var qw = new QueryWrapper<IamPermission>();
        qw.lambda()
                .eq(IamPermission::getModuleId, permission.getModuleId())
                .eq(IamPermission::getGroups, "auth")
                .eq(IamPermission::getParentId, permission.getParentId())
                .eq(IamPermission::getEvent, permission.getEvent())
                .eq(IamPermission::getFlag, permission.getFlag());
        if(permissionService.getList(qw).size() > 0){
            return "权限配置重复";
        }
        return super.beforeCreate(entity);
    }
}
